package com.Guo.auth;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

/**
 * @author Admin
 * @project WebSecurityConfig
 * @description
 * @date 2020-12-09-10:10
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * 在ioc中注入一个bean
     * 每次运行就算是相同的字符串，生成的密码也不一样
     * 每次生成的salt不一样
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder(){
        //使用这么一个实现类
        return new BCryptPasswordEncoder();
    }

    /**
     * 修改密码的加密模式
     */
    @Autowired
    private PasswordEncoder passwordEncoder;

    /**
     * 自定义的认证逻辑
     */
    @Autowired
    private UserDetailsService userDetailsService;

    /**
     * 登录成功逻辑处理
     */
    @Autowired
    private AuthenticationSuccessHandler authenticationSuccessHandler;



    /**
     * 登录失败逻辑处理
     */
    @Autowired
    private AuthenticationFailureHandler authenticationFailureHandler;

    /**
     * 重写三个configure方法
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //springSecurity拥有自带的认证方法
        //将默认的认证方法替换成我们自己定义的认证方法
        auth.userDetailsService(userDetailsService)
                //设置密码的加密方式，需要使用springSecurity自带的
                .passwordEncoder(passwordEncoder);
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        super.configure(web);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //关闭csrf跨域
        http.cors().and().csrf().disable();

        //所有请求都需要认证
        http.authorizeRequests().anyRequest().authenticated();

        http.formLogin().permitAll()
                //登录成功时替换为我们自定义登录成功的处理器
                .successHandler(authenticationSuccessHandler)
                //登录失败时替换为我们自定义登录失败的处理器
                .failureHandler(authenticationFailureHandler);

    }
}
